package mac10.util;

import java.util.ArrayList;

import mac10.models.Cell;
import mac10.models.Point;
import mac10.models.WorldModel;

/*
 * only used in NavTest.main
 */

@Deprecated
public class AStarNormal {

	WorldModel world;
	Node start, goal;
	ArrayList<Node> closedlist;
	OpenList openlist;
	private boolean avoidFences, avoidCows, avoidAgents;
	
	public AStarNormal(WorldModel world, Point start, Point goal)
	{
		this.world = world;
		int fstart = 0 + start.maxNorm(goal);
		this.start = new Node(start, 0, fstart);
		this.goal = new Node(goal, Integer.MAX_VALUE, Integer.MAX_VALUE);
		this.openlist = new OpenList();
		this.closedlist = new ArrayList<Node>();
	}

	/**
	 * Calculates the path from start to goal
	 * If path was found, the path can be reconstructed recursively with the predecessor of the goal-node
	 * @return goal-node or null if no path was found
	 */
	public Node AStar()
	{
		openlist.add(start);
		
		while(!openlist.isEmpty())
		{
			Node curr = openlist.removeMin();
//			System.out.println(curr);
			if (curr.equals(goal))
			{
				openlist = new OpenList();
				closedlist = new ArrayList<Node>();
				return curr;
			}
			expandNode(curr);
			
			closedlist.add(curr);
		}
		openlist = new OpenList();
		closedlist = new ArrayList<Node>();
		return null;
	}
	
	private void expandNode(Node curr)
	{
		ArrayList<Cell> cells = this.world.getNeighbours(curr.getX(), curr.getY());
        for (Cell cell : cells) {
        	
        	// these cells are never accessible
			if (cell.isObstacle() || cell.isSwitch())
				continue;
			if(avoidFences && cell.isFence() && !cell.isOpen())
				continue;
			if(avoidCows && cell.isCow())
				continue;
			if(avoidAgents && (cell.isAllyAgent() || cell.isEnemyAgent()))
				continue;
			
			int fsucc = curr.getG() + 1 + goal.maxNorm(cell);
			Node successor = new Node(cell, curr.getG() + 1, fsucc, curr);
//			System.out.println("\t"+successor+" f: "+fsucc);
			if (closedlist.contains(successor))
				continue;
			
			if (openlist.contains(successor))
			{
				openlist.updateNode(successor);
			}
			else
			{
				openlist.add(successor);
			}
		}
	}

	/**
	 * @return the avoidFences
	 */
	public boolean isAvoidFences() {
		return avoidFences;
	}

	/**
	 * @param avoidFences the avoidFences to set
	 */
	public void setAvoidFences(boolean avoidFences) {
		this.avoidFences = avoidFences;
	}

	/**
	 * @return the avoidCows
	 */
	public boolean isAvoidCows() {
		return avoidCows;
	}

	/**
	 * @param avoidCows the avoidCows to set
	 */
	public void setAvoidCows(boolean avoidCows) {
		this.avoidCows = avoidCows;
	}

	/**
	 * @return the avoidAgents
	 */
	public boolean isAvoidAgents() {
		return avoidAgents;
	}

	/**
	 * @param avoidAgents the avoidAgents to set
	 */
	public void setAvoidAgents(boolean avoidAgents) {
		this.avoidAgents = avoidAgents;
	}
}
